package cn.myframe.utils;

import org.apache.commons.lang.StringUtils;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
 
/**
 * AESTest.java
 * 
 * @author Techzero
 * @Email techzero@163.com
 * @Time 2013-12-12 下午1:25:44
 */
public class AESSecurityUtil {
	
	private static final String KEY_ALGORITHM = "AES";
	public static final String CIPHER_ALGORITHM="AES/ECB/PKCS7Padding"; 
	public static String SHAREDKEY = "F97CA1C836F5200625619A25576C16A1C9E6B87B9A2784230C309F39E9999E65";
	private static boolean init = false;
 
    public static void main(String[] args) throws Exception {
        String content = "888999";
        String password = "myframe.cn";
        System.out.println("密　钥：" + password);
        System.out.println("加密前：" + content);
        // 加密
        String encryptResult = encrypts(content, password);
        System.out.println("加密后：" + encryptResult);
        // 解密
        String decryptResult = decrypt("20D70F68FD499982388384A87D2BC10E", password);
        System.out.println("解密后：" + decryptResult);
    }
 
    /**
     * 加密
     * 
     * @param content
     *            待加密内容
     * @param key
     *            加密的密钥
     * @return
     */
    public static String encrypts(String content, String key) {
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(key.getBytes());
            kgen.init(128, random);
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            byte[] byteContent = content.getBytes("utf-8");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
            byte[] byteRresult = cipher.doFinal(byteContent);
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < byteRresult.length; i++) {
                String hex = Integer.toHexString(byteRresult[i] & 0xFF);
                if (hex.length() == 1) {
                    hex = '0' + hex;
                }
                sb.append(hex.toUpperCase());
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 解密
     * 
     * @param content
     *            待解密内容
     * @param key
     *            解密的密钥
     * @return
     */
    public static String decrypts(String content, String key) {
        if (content.length() < 1){
            return null;
        }
        byte[] byteRresult = new byte[content.length() / 2];
        for (int i = 0; i < content.length() / 2; i++) {
            int high = Integer.parseInt(content.substring(i * 2, i * 2 + 1), 16);
            int low = Integer.parseInt(content.substring(i * 2 + 1, i * 2 + 2), 16);
            byteRresult[i] = (byte) (high * 16 + low);
        }
        try {
            KeyGenerator kgen = KeyGenerator.getInstance("AES");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
            random.setSeed(key.getBytes());
            kgen.init(128, random);
            SecretKey secretKey = kgen.generateKey();
            byte[] enCodeFormat = secretKey.getEncoded();
            SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
            byte[] result = cipher.doFinal(byteRresult);
            return new String(result);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (IllegalBlockSizeException e) {
            e.printStackTrace();
        } catch (BadPaddingException e) {
            e.printStackTrace();
        }
        return null;
    }
    
	private static String byte2HexString ( byte[] data ) {
        String result = "" ;
        for ( int i = 0 ; i < data.length ; i++ ) {
            result += Integer.toString ( ( data[ i ] & 0xff ) + 0x100 , 16 ).substring ( 1 ).toUpperCase () ;
        }
        return result ;
    }

    private static byte[] String2Bytes(String str){
        byte[] res = str.getBytes();
        byte[] data = new byte[res.length/2];
        for ( int i = 0 ; i < (res.length/2) ; i++) {
            data[i] = Integer.valueOf(str.substring(i*2,(i*2)+2),16).byteValue();
        }
        return data;
    }
	
	public static String initSecretKey(){
		initProvider();
		KeyGenerator kg = null;
		try {
			kg = KeyGenerator.getInstance(KEY_ALGORITHM, "BC");
		} catch (Exception e) {
			return null;
		}
		kg.init(256);
		SecretKey secretKey = kg.generateKey();
		return byte2HexString(secretKey.getEncoded());
	}
	
	public static Key toKey(byte[] key) throws Exception{  
        SecretKey secretKey=new SecretKeySpec(key,KEY_ALGORITHM);  
        return secretKey;  
    }  
	
	public static String encrypt(String data,String key) throws Exception{  
		initProvider();
		key=SHAREDKEY;
        Key k=toKey(String2Bytes(key));  
        Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");  
        cipher.init(Cipher.ENCRYPT_MODE, k); 
        byte[] cipherData = cipher.doFinal(data.getBytes());
        return  byte2HexString(cipherData);
    }
	
	public static String encrypt(String data) throws Exception{  
		initProvider();
        Key k=toKey(String2Bytes(SHAREDKEY));  
        Cipher cipher=Cipher.getInstance(CIPHER_ALGORITHM, "BC");  
        cipher.init(Cipher.ENCRYPT_MODE, k); 
        byte[] cipherData = cipher.doFinal(data.getBytes());
        return  byte2HexString(cipherData);
    }

	public static String decrypt(String data, String key) throws Exception {
		initProvider();
		key=SHAREDKEY;
        Key k=toKey(String2Bytes(key));
		Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
		cipher.init(Cipher.DECRYPT_MODE, k);
		byte[] cipherData = cipher.doFinal(String2Bytes(data));
		return new String(cipherData);
	}
	
	
	public static String decrypt(String data){
		try {
			if(StringUtils.isNotEmpty(data)){
				return decrypt(data,SHAREDKEY);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
		
	}
	
	private static void initProvider(){
		if(init){
            return;
        }
		Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		try {
			String sharedKey = SHAREDKEY;
			if(cn.myframe.utils.StringUtils.isNotEmpty(sharedKey)){
				SHAREDKEY = sharedKey;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		init = true;
	}
 
}